!! Copyright (C) 2009,2010,2011,2012  Marco Restelli
!!
!! This file is part of:
!!   FEMilaro -- Finite Element Method toolkit
!!
!! FEMilaro is free software; you can redistribute it and/or modify it
!! under the terms of the GNU General Public License as published by
!! the Free Software Foundation; either version 3 of the License, or
!! (at your option) any later version.
!!
!! FEMilaro is distributed in the hope that it will be useful, but
!! WITHOUT ANY WARRANTY; without even the implied warranty of
!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
!! General Public License for more details.
!!
!! You should have received a copy of the GNU General Public License
!! along with FEMilaro; If not, see <http://www.gnu.org/licenses/>.
!!
!! author: Marco Restelli                   <marco.restelli@gmail.com>

!>\brief
!! Interfaces to non standard intrinsics and various simple utilities
!!
!! \n
!!
!! The utilities collected in this module typically depend on the use
!! of OpenMP, MPI etc, and concern timings and aborting.
!!
!! Notice that, to get meaningful timings, it is important to use the
!! correct types and kinds.
!<----------------------------------------------------------------------
module mod_utils

 !$ use omp_lib, only: &
 !$   omp_get_wtime

!-----------------------------------------------------------------------

 implicit none

!-----------------------------------------------------------------------

 public :: &
   my_abort,  &
   t_realtime, my_second

 private

 integer, parameter :: t_realtime = &
   !$ kind(0.0d0) ! default double: omp_get_wtime()
   !$ integer, parameter :: omp_dummy1 = &
   kind(0.0) ! default real: for the standard cpu_time

!-----------------------------------------------------------------------

 contains

!-----------------------------------------------------------------------

 !> Stop the execution
 subroutine my_abort()
   
   call abort()
 
 end subroutine my_abort
                   
!-----------------------------------------------------------------------

 !> Get CPU time (only time differences are meaningful)
 function my_second() result(t)
  real(t_realtime) :: t

   !$ t = omp_get_wtime()

 !$ contains

  !$ subroutine omp_dummy2(t)
  !$ real(omp_dummy1), intent(out) :: t
  intrinsic :: cpu_time

   call cpu_time(t)
  !$ end subroutine omp_dummy2

 end function my_second
                   
!-----------------------------------------------------------------------

end module mod_utils

